package biz.datalk.industrialland.common.log.service.impl;

import biz.datalk.industrialland.common.log.def.LogTypeEnum;
import biz.datalk.industrialland.common.log.def.OptEnum;
import biz.datalk.industrialland.common.log.def.OptResultEnum;
import biz.datalk.industrialland.common.log.pojo.bo.LogBO;
import biz.datalk.industrialland.common.log.service.ISysLogService;
import biz.datalk.industrialland.common.log.task.SysLogSaveMongo;
import biz.datalk.industrialland.common.log.task.SysLogSaveRunnable;
import biz.datalk.industrialland.common.log.util.SysLogUtil;
import biz.datalk.industrialland.common.util.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.servlet.http.HttpServletRequest;

/**
 * 日志服务实现类
 *
 * 存储到 MongoDB
 *
 * @author tarofang@163.com
 * @date 2020-11-24
 */
@Slf4j
public class SysLogServiceMongoImpl implements ISysLogService {


    private final String logServerIp;
    private final String serverPrivateKey;
    private final ThreadPoolTaskExecutor logTaskThreadPoolExecutor;
    private final MongoTemplate mongoTemplate;

    public SysLogServiceMongoImpl(MongoTemplate mongoTemplate, String logServerIp, String serverPrivateKey, ThreadPoolTaskExecutor logTaskThreadPoolExecutor) {
        this.logServerIp = logServerIp;
        this.serverPrivateKey = serverPrivateKey;
        this.logTaskThreadPoolExecutor = logTaskThreadPoolExecutor;
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public void saveLogBo(LogBO logBO) {
        this.savePreview(logBO, Boolean.TRUE);
    }

    @Override
    public void saveLog(Long sysUserId, String username, LogTypeEnum logTypeEnum, OptEnum optEnum, String logContent, //
                        OptResultEnum opResult, String reqResult, String reqBodyPlaintext, long costMillisecond) {
        sysUserId = sysUserId == null ? -1L : sysUserId;
        username = StringUtils.isBlank(username) ? "" : username.trim();
        HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
        LogBO logBO = SysLogUtil.pkgLogBo(request, sysUserId, username, logTypeEnum, optEnum, logContent, opResult, reqResult, reqBodyPlaintext, costMillisecond, this.logServerIp);
        this.savePreview(logBO, Boolean.FALSE);
    }

    @Override
    public void saveLog(Long sysUserId, String username, LogTypeEnum logTypeEnum, OptEnum optEnum, String logContent, //
                        OptResultEnum opResult, String reqResult, String reqBodyPlaintext) {
        this.saveLog(sysUserId, username, logTypeEnum, optEnum, logContent, opResult, reqResult, reqBodyPlaintext, 0L);
    }

    @Override
    public void saveLog(LogTypeEnum logTypeEnum, OptEnum optEnum, String logContent, OptResultEnum opResult, String reqResult, String reqBodyPlaintext) {
        this.saveLog(null, null, logTypeEnum, optEnum, logContent, opResult, reqResult, reqBodyPlaintext, 0L);
    }

    private void savePreview(LogBO logBO, boolean needDecryptReqBodyParam) {
        if (log.isDebugEnabled()) {
            log.debug("SysLogServiceMongoImpl ============================== into");
            log.debug("SysLogServiceMongoImpl: LogBO: {}, needDecryptReqBodyParam: {}", logBO, needDecryptReqBodyParam);
        }
        try {
            SysLogSaveRunnable task = new SysLogSaveMongo(this.mongoTemplate, this.serverPrivateKey, logBO, needDecryptReqBodyParam);
            logTaskThreadPoolExecutor.execute(task);
        } finally {
            if (log.isDebugEnabled()) {
                log.debug("SysLogServiceMongoImpl ============================== out");
            }
        }
    }


}
